package org.zjx.model.route;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.zjx.entity.Location;
import org.zjx.enums.route.RouteType;

import java.io.Serializable;

/**
 * 路由抽象基类
 * 实现Route接口的通用功能
 */
@Data
@NoArgsConstructor
public abstract class AbstractRoute implements Route, Serializable {
    private static final long serialVersionUID = 1L;
    protected Location start;
    protected Location end;
    protected int time;
    protected RouteType type;
    protected boolean reversible;

    /**
     * 构造函数
     *
     * @param start      起点（非null）
     * @param end        终点（非null）
     * @param time       耗时（秒，必须>0）
     * @param type       路由类型（非null）
     * @param reversible 是否可逆
     * @throws IllegalArgumentException 如果参数不合法
     */
    protected AbstractRoute(Location start, Location end,
                            int time, RouteType type,
                            boolean reversible) {
        if (start == null || end == null || type == null) {
            throw new IllegalArgumentException("关键参数不能为null");
        }
        if (time <= 0) {
            throw new IllegalArgumentException("耗时必须为正数");
        }

        this.start = start;
        this.end = end;
        this.time = time;
        this.type = type;
        this.reversible = reversible;
    }

    // ---------- 实现Route接口 ----------
    @Override
    public Location getStart() {
        return start;
    }

    @Override
    public Location getEnd() {
        return end;
    }

    @Override
    public int getTime() {
        return time;
    }

    @Override
    public RouteType getType() {
        return type;
    }

    @Override
    public boolean isReversible() {
        return reversible;
    }

    @Override
    @JsonIgnore
    public Route getReverseRoute() {
        if (!reversible) {
            throw new UnsupportedOperationException(
                    "该类型路由不支持反向操作: " + getClass().getSimpleName());
        }
        return createReverseRoute();
    }

    /**
     * 创建反向路由的模板方法
     * 由具体子类实现
     */
    protected abstract Route createReverseRoute();

    @Override
    public String toString() {
        return String.format("%s[%s → %s, %ds, %s]",
                getClass().getSimpleName(),
                start,
                end,
                time,
                reversible ? "双向" : "单向");
    }
}